home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / Image.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  30.9 KB  |  1,204 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. VERSION = '1.1.5'
  5.  
  6. try:
  7.     import warnings
  8. except ImportError:
  9.     warnings = None
  10.  
  11.  
  12. class _imaging_not_installed:
  13.     
  14.     def __getattr__(self, id):
  15.         raise ImportError('The _imaging C module is not installed')
  16.  
  17.  
  18.  
  19. try:
  20.     __import__('FixTk')
  21. except ImportError:
  22.     pass
  23.  
  24.  
  25. try:
  26.     import _imaging
  27.     core = _imaging
  28.     del _imaging
  29. except ImportError:
  30.     v = None
  31.     core = _imaging_not_installed()
  32.     if str(v)[:20] == 'Module use of python' and warnings:
  33.         warnings.warn('The _imaging extension was built for another version of Python; most PIL functions will be disabled', RuntimeWarning)
  34.     
  35. except:
  36.     warnings
  37.  
  38. import ImagePalette
  39. import os
  40. import string
  41. import sys
  42. from types import IntType, StringType, TupleType
  43.  
  44. try:
  45.     UnicodeStringType = type(unicode(''))
  46.     
  47.     def isStringType(t):
  48.         if not isinstance(t, StringType):
  49.             pass
  50.         return isinstance(t, UnicodeStringType)
  51.  
  52. except NameError:
  53.     
  54.     def isStringType(t):
  55.         return isinstance(t, StringType)
  56.  
  57.  
  58.  
  59. def isTupleType(t):
  60.     return isinstance(t, TupleType)
  61.  
  62.  
  63. def isImageType(t):
  64.     return hasattr(t, 'im')
  65.  
  66.  
  67. def isDirectory(f):
  68.     if isStringType(f):
  69.         pass
  70.     return os.path.isdir(f)
  71.  
  72. from operator import isNumberType, isSequenceType
  73. DEBUG = 0
  74. NONE = 0
  75. FLIP_LEFT_RIGHT = 0
  76. FLIP_TOP_BOTTOM = 1
  77. ROTATE_90 = 2
  78. ROTATE_180 = 3
  79. ROTATE_270 = 4
  80. AFFINE = 0
  81. EXTENT = 1
  82. PERSPECTIVE = 2
  83. QUAD = 3
  84. MESH = 4
  85. NONE = 0
  86. NEAREST = 0
  87. ANTIALIAS = 1
  88. LINEAR = BILINEAR = 2
  89. CUBIC = BICUBIC = 3
  90. NONE = 0
  91. NEAREST = 0
  92. ORDERED = 1
  93. RASTERIZE = 2
  94. FLOYDSTEINBERG = 3
  95. WEB = 0
  96. ADAPTIVE = 1
  97. NORMAL = 0
  98. SEQUENCE = 1
  99. CONTAINER = 2
  100. ID = []
  101. OPEN = { }
  102. MIME = { }
  103. SAVE = { }
  104. EXTENSION = { }
  105. _MODEINFO = {
  106.     '1': ('L', 'L', ('1',)),
  107.     'L': ('L', 'L', ('L',)),
  108.     'I': ('L', 'I', ('I',)),
  109.     'F': ('L', 'F', ('F',)),
  110.     'P': ('RGB', 'L', ('P',)),
  111.     'RGB': ('RGB', 'L', ('R', 'G', 'B')),
  112.     'RGBX': ('RGB', 'L', ('R', 'G', 'B', 'X')),
  113.     'RGBA': ('RGB', 'L', ('R', 'G', 'B', 'A')),
  114.     'CMYK': ('RGB', 'L', ('C', 'M', 'Y', 'K')),
  115.     'YCbCr': ('RGB', 'L', ('Y', 'Cb', 'Cr')) }
  116. MODES = _MODEINFO.keys()
  117. MODES.sort()
  118. _MAPMODES = ('L', 'P', 'RGBX', 'RGBA', 'CMYK', 'I;16', 'I;16B')
  119.  
  120. def getmodebase(mode):
  121.     if mode == 'LA':
  122.         return 'L'
  123.     
  124.     if mode == 'PA':
  125.         return 'RGB'
  126.     
  127.     return _MODEINFO[mode][0]
  128.  
  129.  
  130. def getmodetype(mode):
  131.     if mode == 'LA':
  132.         return 'L'
  133.     
  134.     if mode == 'PA':
  135.         return 'L'
  136.     
  137.     return _MODEINFO[mode][1]
  138.  
  139.  
  140. def getmodebands(mode):
  141.     if mode == 'LA':
  142.         return ('L', 'A')
  143.     
  144.     if mode == 'PA':
  145.         return ('P', 'A')
  146.     
  147.     return len(_MODEINFO[mode][2])
  148.  
  149. _initialized = 0
  150.  
  151. def preinit():
  152.     '''Load standard file format drivers.'''
  153.     global _initialized
  154.     if _initialized >= 1:
  155.         return None
  156.     
  157.     for m in ('Bmp', 'Gif', 'Jpeg', 'Ppm', 'Png', 'Tiff'):
  158.         
  159.         try:
  160.             __import__('%sImagePlugin' % m, globals(), locals(), [])
  161.         continue
  162.         except ImportError:
  163.             continue
  164.         
  165.  
  166.     
  167.     _initialized = 1
  168.  
  169.  
  170. def init():
  171.     '''Load all file format drivers.'''
  172.     global _initialized
  173.     if _initialized >= 2:
  174.         return None
  175.     
  176.     visited = { }
  177.     directories = sys.path
  178.     
  179.     try:
  180.         directories = directories + [
  181.             os.path.dirname(__file__)]
  182.     except NameError:
  183.         pass
  184.  
  185.     for directory in filter(isDirectory, directories):
  186.         fullpath = os.path.abspath(directory)
  187.         if visited.has_key(fullpath):
  188.             continue
  189.         
  190.         for file in os.listdir(directory):
  191.             if file[-14:] == 'ImagePlugin.py':
  192.                 (f, e) = os.path.splitext(file)
  193.                 
  194.                 try:
  195.                     sys.path.insert(0, directory)
  196.                     
  197.                     try:
  198.                         __import__(f, globals(), locals(), [])
  199.                     finally:
  200.                         del sys.path[0]
  201.  
  202.                 except ImportError:
  203.                     if DEBUG:
  204.                         print 'Image: failed to import', f, ':', sys.exc_value
  205.                     
  206.                 except:
  207.                     DEBUG
  208.                 
  209.  
  210.             None<EXCEPTION MATCH>ImportError
  211.         
  212.         visited[fullpath] = None
  213.     
  214.     if OPEN or SAVE:
  215.         _initialized = 2
  216.     
  217.  
  218.  
  219. def _getdecoder(mode, decoder_name, args, extra = ()):
  220.     if args is None:
  221.         args = ()
  222.     elif not isTupleType(args):
  223.         args = (args,)
  224.     
  225.     
  226.     try:
  227.         decoder = getattr(core, decoder_name + '_decoder')
  228.         return apply(decoder, (mode,) + args + extra)
  229.     except AttributeError:
  230.         raise IOError('decoder %s not available' % decoder_name)
  231.  
  232.  
  233.  
  234. def _getencoder(mode, encoder_name, args, extra = ()):
  235.     if args is None:
  236.         args = ()
  237.     elif not isTupleType(args):
  238.         args = (args,)
  239.     
  240.     
  241.     try:
  242.         encoder = getattr(core, encoder_name + '_encoder')
  243.         return apply(encoder, (mode,) + args + extra)
  244.     except AttributeError:
  245.         raise IOError('encoder %s not available' % encoder_name)
  246.  
  247.  
  248.  
  249. class _E:
  250.     
  251.     def __init__(self, data):
  252.         self.data = data
  253.  
  254.     
  255.     def __coerce__(self, other):
  256.         return (self, _E(other))
  257.  
  258.     
  259.     def __add__(self, other):
  260.         return _E((self.data, '__add__', other.data))
  261.  
  262.     
  263.     def __mul__(self, other):
  264.         return _E((self.data, '__mul__', other.data))
  265.  
  266.  
  267.  
  268. def _getscaleoffset(expr):
  269.     stub = [
  270.         'stub']
  271.     data = expr(_E(stub)).data
  272.     
  273.     try:
  274.         (a, b, c) = data
  275.         if a is stub and b == '__mul__' and isNumberType(c):
  276.             return (c, 0.0)
  277.         
  278.         if a is stub and b == '__add__' and isNumberType(c):
  279.             return (1.0, c)
  280.     except TypeError:
  281.         pass
  282.  
  283.     
  284.     try:
  285.         (a, b, c) = ()
  286.         d = data
  287.         e = None
  288.         if a is stub and b == '__mul__' and isNumberType(c) and d == '__add__' and isNumberType(e):
  289.             return (c, e)
  290.     except TypeError:
  291.         pass
  292.  
  293.     raise ValueError('illegal expression')
  294.  
  295.  
  296. class Image:
  297.     format = None
  298.     format_description = None
  299.     
  300.     def __init__(self):
  301.         self.im = None
  302.         self.mode = ''
  303.         self.size = (0, 0)
  304.         self.palette = None
  305.         self.info = { }
  306.         self.category = NORMAL
  307.         self.readonly = 0
  308.  
  309.     
  310.     def _new(self, im):
  311.         new = Image()
  312.         new.im = im
  313.         new.mode = im.mode
  314.         new.size = im.size
  315.         new.palette = self.palette
  316.         if im.mode == 'P':
  317.             new.palette = ImagePalette.ImagePalette()
  318.         
  319.         
  320.         try:
  321.             new.info = self.info.copy()
  322.         except AttributeError:
  323.             new.info = { }
  324.             for k, v in self.info:
  325.                 new.info[k] = v
  326.             
  327.  
  328.         return new
  329.  
  330.     _makeself = _new
  331.     
  332.     def _copy(self):
  333.         self.load()
  334.         self.im = self.im.copy()
  335.         self.readonly = 0
  336.  
  337.     
  338.     def _dump(self, file = None, format = None):
  339.         import tempfile
  340.         if not file:
  341.             file = tempfile.mktemp()
  342.         
  343.         self.load()
  344.         if not format or format == 'PPM':
  345.             self.im.save_ppm(file)
  346.         else:
  347.             file = file + '.' + format
  348.             self.save(file, format)
  349.         return file
  350.  
  351.     
  352.     def tostring(self, encoder_name = 'raw', *args):
  353.         '''Return image as a binary string'''
  354.         if len(args) == 1 and isTupleType(args[0]):
  355.             args = args[0]
  356.         
  357.         if encoder_name == 'raw' and args == ():
  358.             args = self.mode
  359.         
  360.         self.load()
  361.         e = _getencoder(self.mode, encoder_name, args)
  362.         e.setimage(self.im)
  363.         data = []
  364.         while None:
  365.             (l, s, d) = e.encode(65536)
  366.             if s:
  367.                 break
  368.                 continue
  369.         if s < 0:
  370.             raise RuntimeError('encoder error %d in tostring' % s)
  371.         
  372.         return string.join(data, '')
  373.  
  374.     
  375.     def tobitmap(self, name = 'image'):
  376.         '''Return image as an XBM bitmap'''
  377.         self.load()
  378.         if self.mode != '1':
  379.             raise ValueError('not a bitmap')
  380.         
  381.         data = self.tostring('xbm')
  382.         return string.join([
  383.             '#define %s_width %d\n' % (name, self.size[0]),
  384.             '#define %s_height %d\n' % (name, self.size[1]),
  385.             'static char %s_bits[] = {\n' % name,
  386.             data,
  387.             '};'], '')
  388.  
  389.     
  390.     def fromstring(self, data, decoder_name = 'raw', *args):
  391.         '''Load data to image from binary string'''
  392.         if len(args) == 1 and isTupleType(args[0]):
  393.             args = args[0]
  394.         
  395.         if decoder_name == 'raw' and args == ():
  396.             args = self.mode
  397.         
  398.         d = _getdecoder(self.mode, decoder_name, args)
  399.         d.setimage(self.im)
  400.         s = d.decode(data)
  401.         if s[0] >= 0:
  402.             raise ValueError('not enough image data')
  403.         
  404.         if s[1] != 0:
  405.             raise ValueError('cannot decode image data')
  406.         
  407.  
  408.     
  409.     def load(self):
  410.         '''Explicitly load pixel data.'''
  411.         if self.im and self.palette and self.palette.dirty:
  412.             apply(self.im.putpalette, self.palette.getdata())
  413.             self.palette.dirty = 0
  414.             self.palette.mode = 'RGB'
  415.             self.palette.rawmode = None
  416.             if self.info.has_key('transparency'):
  417.                 self.im.putpalettealpha(self.info['transparency'], 0)
  418.                 self.palette.mode = 'RGBA'
  419.             
  420.         
  421.  
  422.     
  423.     def verify(self):
  424.         '''Verify file contents.'''
  425.         pass
  426.  
  427.     
  428.     def convert(self, mode = None, data = None, dither = None, palette = WEB, colors = 256):
  429.         '''Convert to other pixel format'''
  430.         if not mode:
  431.             if self.mode == 'P':
  432.                 self.load()
  433.                 if self.palette:
  434.                     mode = self.palette.mode
  435.                 else:
  436.                     mode = 'RGB'
  437.             else:
  438.                 return self.copy()
  439.         
  440.         self.load()
  441.         if data:
  442.             if mode not in ('L', 'RGB'):
  443.                 raise ValueError('illegal conversion')
  444.             
  445.             im = self.im.convert_matrix(mode, data)
  446.             return self._new(im)
  447.         
  448.         if mode == 'P' and palette == ADAPTIVE:
  449.             im = self.im.quantize(colors)
  450.             return self._new(im)
  451.         
  452.         if dither is None:
  453.             dither = FLOYDSTEINBERG
  454.         
  455.         
  456.         try:
  457.             im = self.im.convert(mode, dither)
  458.         except ValueError:
  459.             
  460.             try:
  461.                 im = self.im.convert(getmodebase(self.mode))
  462.                 im = im.convert(mode, dither)
  463.             except KeyError:
  464.                 raise ValueError('illegal conversion')
  465.             except:
  466.                 None<EXCEPTION MATCH>KeyError
  467.             
  468.  
  469.             None<EXCEPTION MATCH>KeyError
  470.  
  471.         return self._new(im)
  472.  
  473.     
  474.     def quantize(self, colors = 256, method = 0, kmeans = 0, palette = None):
  475.         self.load()
  476.         if palette:
  477.             palette.load()
  478.             if palette.mode != 'P':
  479.                 raise ValueError('bad mode for palette image')
  480.             
  481.             if self.mode != 'RGB' and self.mode != 'L':
  482.                 raise ValueError('only RGB or L mode images can be quantized to a palette')
  483.             
  484.             im = self.im.convert('P', 1, palette.im)
  485.             return self._makeself(im)
  486.         
  487.         im = self.im.quantize(colors, method, kmeans)
  488.         return self._new(im)
  489.  
  490.     
  491.     def copy(self):
  492.         '''Copy raster data'''
  493.         self.load()
  494.         im = self.im.copy()
  495.         return self._new(im)
  496.  
  497.     
  498.     def crop(self, box = None):
  499.         '''Crop region from image'''
  500.         self.load()
  501.         if box is None:
  502.             return self.copy()
  503.         
  504.         return _ImageCrop(self, box)
  505.  
  506.     
  507.     def draft(self, mode, size):
  508.         '''Configure image decoder'''
  509.         pass
  510.  
  511.     
  512.     def _expand(self, xmargin, ymargin = None):
  513.         if ymargin is None:
  514.             ymargin = xmargin
  515.         
  516.         self.load()
  517.         return self._new(self.im.expand(xmargin, ymargin, 0))
  518.  
  519.     
  520.     def filter(self, filter):
  521.         '''Apply environment filter to image'''
  522.         self.load()
  523.         Filter = Filter
  524.         import ImageFilter
  525.         if not isinstance(filter, Filter):
  526.             filter = filter()
  527.         
  528.         if self.im.bands == 1:
  529.             return self._new(filter.filter(self.im))
  530.         
  531.         ims = []
  532.         for c in range(self.im.bands):
  533.             ims.append(self._new(filter.filter(self.im.getband(c))))
  534.         
  535.         return merge(self.mode, ims)
  536.  
  537.     
  538.     def getbands(self):
  539.         '''Get band names'''
  540.         return _MODEINFO[self.mode][2]
  541.  
  542.     
  543.     def getbbox(self):
  544.         '''Get bounding box of actual data (non-zero pixels) in image'''
  545.         self.load()
  546.         return self.im.getbbox()
  547.  
  548.     
  549.     def getcolors(self, maxcolors = 256):
  550.         '''Get colors from image, up to given limit'''
  551.         self.load()
  552.         if self.mode in ('1', 'L', 'P'):
  553.             h = self.im.histogram()
  554.             out = []
  555.             for i in range(256):
  556.                 if h[i]:
  557.                     out.append((h[i], i))
  558.                     continue
  559.             
  560.             if len(out) > maxcolors:
  561.                 return None
  562.             
  563.             return out
  564.         
  565.         return self.im.getcolors(maxcolors)
  566.  
  567.     
  568.     def getdata(self, band = None):
  569.         '''Get image data as sequence object.'''
  570.         self.load()
  571.         if band is not None:
  572.             return self.im.getband(band)
  573.         
  574.         return self.im
  575.  
  576.     
  577.     def getextrema(self):
  578.         '''Get min/max value'''
  579.         self.load()
  580.         if self.im.bands > 1:
  581.             extrema = []
  582.             for i in range(self.im.bands):
  583.                 extrema.append(self.im.getband(i).getextrema())
  584.             
  585.             return tuple(extrema)
  586.         
  587.         return self.im.getextrema()
  588.  
  589.     
  590.     def getim(self):
  591.         '''Get PyCObject pointer to internal image memory'''
  592.         self.load()
  593.         return self.im.ptr
  594.  
  595.     
  596.     def getpalette(self):
  597.         '''Get palette contents.'''
  598.         self.load()
  599.         
  600.         try:
  601.             return map(ord, self.im.getpalette())
  602.         except ValueError:
  603.             return None
  604.  
  605.  
  606.     
  607.     def getpixel(self, xy):
  608.         '''Get pixel value'''
  609.         self.load()
  610.         return self.im.getpixel(xy)
  611.  
  612.     
  613.     def getprojection(self):
  614.         '''Get projection to x and y axes'''
  615.         self.load()
  616.         (x, y) = self.im.getprojection()
  617.         return (map(ord, x), map(ord, y))
  618.  
  619.     
  620.     def histogram(self, mask = None, extrema = None):
  621.         '''Take histogram of image'''
  622.         self.load()
  623.         if mask:
  624.             mask.load()
  625.             return self.im.histogram((0, 0), mask.im)
  626.         
  627.         if self.mode in ('I', 'F'):
  628.             if extrema is None:
  629.                 extrema = self.getextrema()
  630.             
  631.             return self.im.histogram(extrema)
  632.         
  633.         return self.im.histogram()
  634.  
  635.     
  636.     def offset(self, xoffset, yoffset = None):
  637.         '''(deprecated) Offset image in horizontal and/or vertical direction'''
  638.         if warnings:
  639.             warnings.warn("'offset' is deprecated; use 'ImageChops.offset' instead", DeprecationWarning)
  640.         
  641.         import ImageChops
  642.         return ImageChops.offset(self, xoffset, yoffset)
  643.  
  644.     
  645.     def paste(self, im, box = None, mask = None):
  646.         '''Paste other image into region'''
  647.         if isImageType(box) and mask is None:
  648.             mask = box
  649.             box = None
  650.         
  651.         if box is None:
  652.             box = (0, 0) + self.size
  653.         
  654.         if len(box) == 2:
  655.             if isImageType(im):
  656.                 size = im.size
  657.             elif isImageType(mask):
  658.                 size = mask.size
  659.             else:
  660.                 raise ValueError('cannot determine region size; use 4-item box')
  661.             box = box + (box[0] + size[0], box[1] + size[1])
  662.         
  663.         if isStringType(im):
  664.             import ImageColor
  665.             im = ImageColor.getcolor(im, self.mode)
  666.         elif isImageType(im):
  667.             im.load()
  668.             if self.mode != im.mode:
  669.                 if self.mode != 'RGB' or im.mode not in ('RGBA', 'RGBa'):
  670.                     im = im.convert(self.mode)
  671.                 
  672.             
  673.             im = im.im
  674.         
  675.         self.load()
  676.         if self.readonly:
  677.             self._copy()
  678.         
  679.         if mask:
  680.             mask.load()
  681.             self.im.paste(im, box, mask.im)
  682.         else:
  683.             self.im.paste(im, box)
  684.  
  685.     
  686.     def point(self, lut, mode = None):
  687.         '''Map image through lookup table'''
  688.         if not isSequenceType(lut):
  689.             if self.mode in ('I', 'I;16', 'F'):
  690.                 (scale, offset) = _getscaleoffset(lut)
  691.                 self.load()
  692.                 return self._new(self.im.point_transform(scale, offset))
  693.             
  694.             lut = map(lut, range(256)) * self.im.bands
  695.         
  696.         if self.mode == 'F':
  697.             raise ValueError('point operation not supported for this mode')
  698.         
  699.         self.load()
  700.         return self._new(self.im.point(lut, mode))
  701.  
  702.     
  703.     def putalpha(self, alpha):
  704.         '''Set alpha layer'''
  705.         self.load()
  706.         if self.readonly:
  707.             self._copy()
  708.         
  709.         if self.mode not in ('LA', 'RGBA'):
  710.             
  711.             try:
  712.                 mode = getmodebase(self.mode) + 'A'
  713.                 
  714.                 try:
  715.                     self.im.setmode(mode)
  716.                 except (AttributeError, ValueError):
  717.                     im = self.im.convert(mode)
  718.                     if im.mode not in ('LA', 'RGBA'):
  719.                         raise ValueError
  720.                     
  721.                     self.im = im
  722.  
  723.                 self.mode = self.im.mode
  724.             except (KeyError, ValueError):
  725.                 raise ValueError('illegal image mode')
  726.             except:
  727.                 None<EXCEPTION MATCH>(KeyError, ValueError)
  728.             
  729.  
  730.         None<EXCEPTION MATCH>(KeyError, ValueError)
  731.         if self.mode == 'LA':
  732.             band = 1
  733.         else:
  734.             band = 3
  735.         if isImageType(alpha):
  736.             if alpha.mode not in ('1', 'L'):
  737.                 raise ValueError('illegal image mode')
  738.             
  739.             alpha.load()
  740.             if alpha.mode == '1':
  741.                 alpha = alpha.convert('L')
  742.             
  743.         else:
  744.             
  745.             try:
  746.                 self.im.fillband(band, alpha)
  747.             except (AttributeError, ValueError):
  748.                 alpha = new('L', self.size, alpha)
  749.  
  750.             return None
  751.         self.im.putband(alpha.im, band)
  752.  
  753.     
  754.     def putdata(self, data, scale = 1.0, offset = 0.0):
  755.         '''Put data from a sequence object into an image.'''
  756.         self.load()
  757.         self.im.putdata(data, scale, offset)
  758.  
  759.     
  760.     def putpalette(self, data, rawmode = 'RGB'):
  761.         '''Put palette data into an image.'''
  762.         self.load()
  763.         if self.mode not in ('L', 'P'):
  764.             raise ValueError('illegal image mode')
  765.         
  766.         if not isStringType(data):
  767.             data = string.join(map(chr, data), '')
  768.         
  769.         self.mode = 'P'
  770.         self.palette = ImagePalette.raw(rawmode, data)
  771.         self.palette.mode = 'RGB'
  772.         self.load()
  773.  
  774.     
  775.     def putpixel(self, xy, value):
  776.         '''Set pixel value'''
  777.         self.load()
  778.         return self.im.putpixel(xy, value)
  779.  
  780.     
  781.     def resize(self, size, resample = NEAREST):
  782.         '''Resize image'''
  783.         if resample not in (NEAREST, BILINEAR, BICUBIC, ANTIALIAS):
  784.             raise ValueError('unknown resampling filter')
  785.         
  786.         self.load()
  787.         if self.mode in ('1', 'P'):
  788.             resample = NEAREST
  789.         
  790.         if resample == ANTIALIAS:
  791.             
  792.             try:
  793.                 im = self.im.stretch(size, resample)
  794.             except AttributeError:
  795.                 raise ValueError('unsupported resampling filter')
  796.             except:
  797.                 None<EXCEPTION MATCH>AttributeError
  798.             
  799.  
  800.         None<EXCEPTION MATCH>AttributeError
  801.         im = self.im.resize(size, resample)
  802.         return self._new(im)
  803.  
  804.     
  805.     def rotate(self, angle, resample = NEAREST):
  806.         '''Rotate image.  Angle given as degrees counter-clockwise.'''
  807.         if resample not in (NEAREST, BILINEAR, BICUBIC):
  808.             raise ValueError('unknown resampling filter')
  809.         
  810.         self.load()
  811.         if self.mode in ('1', 'P'):
  812.             resample = NEAREST
  813.         
  814.         return self._new(self.im.rotate(angle, resample))
  815.  
  816.     
  817.     def save(self, fp, format = None, **params):
  818.         '''Save image to file or stream'''
  819.         if isStringType(fp):
  820.             filename = fp
  821.         elif hasattr(fp, 'name') and isStringType(fp.name):
  822.             filename = fp.name
  823.         else:
  824.             filename = ''
  825.         self.load()
  826.         self.encoderinfo = params
  827.         self.encoderconfig = ()
  828.         preinit()
  829.         ext = string.lower(os.path.splitext(filename)[1])
  830.         if not format:
  831.             
  832.             try:
  833.                 format = EXTENSION[ext]
  834.             except KeyError:
  835.                 init()
  836.                 
  837.                 try:
  838.                     format = EXTENSION[ext]
  839.                 except KeyError:
  840.                     raise KeyError(ext)
  841.                 except:
  842.                     None<EXCEPTION MATCH>KeyError
  843.                 
  844.  
  845.                 None<EXCEPTION MATCH>KeyError
  846.             
  847.  
  848.         None<EXCEPTION MATCH>KeyError
  849.         
  850.         try:
  851.             save_handler = SAVE[string.upper(format)]
  852.         except KeyError:
  853.             init()
  854.             save_handler = SAVE[string.upper(format)]
  855.  
  856.         if isStringType(fp):
  857.             import __builtin__
  858.             fp = __builtin__.open(fp, 'wb')
  859.             close = 1
  860.         else:
  861.             close = 0
  862.         
  863.         try:
  864.             save_handler(self, fp, filename)
  865.         finally:
  866.             if close:
  867.                 fp.close()
  868.             
  869.  
  870.  
  871.     
  872.     def seek(self, frame):
  873.         '''Seek to given frame in sequence file'''
  874.         if frame != 0:
  875.             raise EOFError
  876.         
  877.  
  878.     
  879.     def show(self, title = None, command = None):
  880.         '''Display image (for debug purposes only)'''
  881.         _showxv(self, title, command)
  882.  
  883.     
  884.     def split(self):
  885.         '''Split image into bands'''
  886.         ims = []
  887.         self.load()
  888.         for i in range(self.im.bands):
  889.             ims.append(self._new(self.im.getband(i)))
  890.         
  891.         return tuple(ims)
  892.  
  893.     
  894.     def tell(self):
  895.         '''Return current frame number'''
  896.         return 0
  897.  
  898.     
  899.     def thumbnail(self, size, resample = NEAREST):
  900.         '''Create thumbnail representation (modifies image in place)'''
  901.         (x, y) = self.size
  902.         if x > size[0]:
  903.             y = max(y * size[0] / x, 1)
  904.             x = size[0]
  905.         
  906.         if y > size[1]:
  907.             x = max(x * size[1] / y, 1)
  908.             y = size[1]
  909.         
  910.         size = (x, y)
  911.         if size == self.size:
  912.             return None
  913.         
  914.         self.draft(None, size)
  915.         self.load()
  916.         
  917.         try:
  918.             im = self.resize(size, resample)
  919.         except ValueError:
  920.             if resample != ANTIALIAS:
  921.                 raise 
  922.             
  923.             im = self.resize(size, NEAREST)
  924.  
  925.         self.im = im.im
  926.         self.mode = im.mode
  927.         self.size = size
  928.         self.readonly = 0
  929.  
  930.     
  931.     def transform(self, size, method, data = None, resample = NEAREST, fill = 1):
  932.         '''Transform image'''
  933.         import ImageTransform
  934.         if isinstance(method, ImageTransform.Transform):
  935.             (method, data) = method.getdata()
  936.         
  937.         if data is None:
  938.             raise ValueError('missing method data')
  939.         
  940.         im = new(self.mode, size, None)
  941.         if method == MESH:
  942.             for box, quad in data:
  943.                 im._Image__transformer(box, self, QUAD, quad, resample, fill)
  944.             
  945.         else:
  946.             im._Image__transformer((0, 0) + size, self, method, data, resample, fill)
  947.         return im
  948.  
  949.     
  950.     def __transformer(self, box, image, method, data, resample = NEAREST, fill = 1):
  951.         w = box[2] - box[0]
  952.         h = box[3] - box[1]
  953.         if method == AFFINE:
  954.             data = (data[2], data[0], data[1], data[5], data[3], data[4])
  955.         elif method == EXTENT:
  956.             (x0, y0, x1, y1) = data
  957.             xs = float(x1 - x0) / w
  958.             ys = float(y1 - y0) / h
  959.             method = AFFINE
  960.             data = (x0 + xs / 2, xs, 0, y0 + ys / 2, 0, ys)
  961.         elif method == PERSPECTIVE:
  962.             data = (data[2], data[0], data[1], data[5], data[3], data[4], data[6], data[7])
  963.         elif method == QUAD:
  964.             nw = data[0:2]
  965.             sw = data[2:4]
  966.             se = data[4:6]
  967.             ne = data[6:8]
  968.             (x0, y0) = nw
  969.             As = 1.0 / w
  970.             At = 1.0 / h
  971.             data = (x0, (ne[0] - x0) * As, (sw[0] - x0) * At, ((se[0] - sw[0] - ne[0]) + x0) * As * At, y0, (ne[1] - y0) * As, (sw[1] - y0) * At, ((se[1] - sw[1] - ne[1]) + y0) * As * At)
  972.         else:
  973.             raise ValueError('unknown transformation method')
  974.         if resample not in (NEAREST, BILINEAR, BICUBIC):
  975.             raise ValueError('unknown resampling filter')
  976.         
  977.         image.load()
  978.         self.load()
  979.         if image.mode in ('1', 'P'):
  980.             resample = NEAREST
  981.         
  982.         self.im.transform2(box, image.im, method, data, resample, fill)
  983.  
  984.     
  985.     def transpose(self, method):
  986.         '''Transpose image (flip or rotate in 90 degree steps)'''
  987.         self.load()
  988.         im = self.im.transpose(method)
  989.         return self._new(im)
  990.  
  991.  
  992.  
  993. class _ImageCrop(Image):
  994.     
  995.     def __init__(self, im, box):
  996.         Image.__init__(self)
  997.         (x0, y0, x1, y1) = box
  998.         if x1 < x0:
  999.             x1 = x0
  1000.         
  1001.         if y1 < y0:
  1002.             y1 = y0
  1003.         
  1004.         self.mode = im.mode
  1005.         self.size = (x1 - x0, y1 - y0)
  1006.         self._ImageCrop__crop = (x0, y0, x1, y1)
  1007.         self.im = im.im
  1008.  
  1009.     
  1010.     def load(self):
  1011.         if self._ImageCrop__crop:
  1012.             self.im = self.im.crop(self._ImageCrop__crop)
  1013.             self._ImageCrop__crop = None
  1014.         
  1015.  
  1016.  
  1017.  
  1018. def _wedge():
  1019.     '''Create greyscale wedge (for debugging only)'''
  1020.     return Image()._new(core.wedge('L'))
  1021.  
  1022.  
  1023. def new(mode, size, color = 0):
  1024.     '''Create a new image'''
  1025.     if color is None:
  1026.         return Image()._new(core.new(mode, size))
  1027.     
  1028.     if isStringType(color):
  1029.         import ImageColor
  1030.         color = ImageColor.getcolor(color, mode)
  1031.     
  1032.     return Image()._new(core.fill(mode, size, color))
  1033.  
  1034.  
  1035. def fromstring(mode, size, data, decoder_name = 'raw', *args):
  1036.     '''Load image from string'''
  1037.     if len(args) == 1 and isTupleType(args[0]):
  1038.         args = args[0]
  1039.     
  1040.     if decoder_name == 'raw' and args == ():
  1041.         args = mode
  1042.     
  1043.     im = new(mode, size)
  1044.     im.fromstring(data, decoder_name, args)
  1045.     return im
  1046.  
  1047.  
  1048. def frombuffer(mode, size, data, decoder_name = 'raw', *args):
  1049.     '''Load image from string or buffer'''
  1050.     if len(args) == 1 and isTupleType(args[0]):
  1051.         args = args[0]
  1052.     
  1053.     if decoder_name == 'raw':
  1054.         if args == ():
  1055.             args = (mode, 0, -1)
  1056.         
  1057.         if args[0] in _MAPMODES:
  1058.             im = new(mode, (1, 1))
  1059.             im = im._new(core.map_buffer(data, size, decoder_name, None, 0, args))
  1060.             im.readonly = 1
  1061.             return im
  1062.         
  1063.     
  1064.     return apply(fromstring, (mode, size, data, decoder_name, args))
  1065.  
  1066.  
  1067. def open(fp, mode = 'r'):
  1068.     '''Open an image file, without loading the raster data'''
  1069.     if mode != 'r':
  1070.         raise ValueError('bad mode')
  1071.     
  1072.     if isStringType(fp):
  1073.         import __builtin__
  1074.         filename = fp
  1075.         fp = __builtin__.open(fp, 'rb')
  1076.     else:
  1077.         filename = ''
  1078.     prefix = fp.read(16)
  1079.     preinit()
  1080.     for i in ID:
  1081.         
  1082.         try:
  1083.             (factory, accept) = OPEN[i]
  1084.             if not accept or accept(prefix):
  1085.                 fp.seek(0)
  1086.                 return factory(fp, filename)
  1087.         continue
  1088.         except (SyntaxError, IndexError, TypeError):
  1089.             continue
  1090.         
  1091.  
  1092.     
  1093.     init()
  1094.     for i in ID:
  1095.         
  1096.         try:
  1097.             (factory, accept) = OPEN[i]
  1098.             if not accept or accept(prefix):
  1099.                 fp.seek(0)
  1100.                 return factory(fp, filename)
  1101.         continue
  1102.         except (SyntaxError, IndexError, TypeError):
  1103.             None<EXCEPTION MATCH>(SyntaxError, IndexError, TypeError)
  1104.             None<EXCEPTION MATCH>(SyntaxError, IndexError, TypeError)
  1105.             continue
  1106.         
  1107.  
  1108.     
  1109.     raise IOError('cannot identify image file')
  1110.  
  1111.  
  1112. def blend(im1, im2, alpha):
  1113.     '''Interpolate between images.'''
  1114.     im1.load()
  1115.     im2.load()
  1116.     return im1._new(core.blend(im1.im, im2.im, alpha))
  1117.  
  1118.  
  1119. def composite(image1, image2, mask):
  1120.     '''Create composite image by blending images using a transparency mask'''
  1121.     image = image2.copy()
  1122.     image.paste(image1, None, mask)
  1123.     return image
  1124.  
  1125.  
  1126. def eval(image, *args):
  1127.     '''Evaluate image expression'''
  1128.     return image.point(args[0])
  1129.  
  1130.  
  1131. def merge(mode, bands):
  1132.     '''Merge a set of single band images into a new multiband image.'''
  1133.     if getmodebands(mode) != len(bands) or '*' in mode:
  1134.         raise ValueError('wrong number of bands')
  1135.     
  1136.     for im in bands[1:]:
  1137.         if im.mode != getmodetype(mode):
  1138.             raise ValueError('mode mismatch')
  1139.         
  1140.         if im.size != bands[0].size:
  1141.             raise ValueError('size mismatch')
  1142.             continue
  1143.     
  1144.     im = core.new(mode, bands[0].size)
  1145.     for i in range(getmodebands(mode)):
  1146.         bands[i].load()
  1147.         im.putband(bands[i].im, i)
  1148.     
  1149.     return bands[0]._new(im)
  1150.  
  1151.  
  1152. def register_open(id, factory, accept = None):
  1153.     id = string.upper(id)
  1154.     ID.append(id)
  1155.     OPEN[id] = (factory, accept)
  1156.  
  1157.  
  1158. def register_mime(id, mimetype):
  1159.     MIME[string.upper(id)] = mimetype
  1160.  
  1161.  
  1162. def register_save(id, driver):
  1163.     SAVE[string.upper(id)] = driver
  1164.  
  1165.  
  1166. def register_extension(id, extension):
  1167.     EXTENSION[string.lower(extension)] = string.upper(id)
  1168.  
  1169.  
  1170. def _showxv(image, title = None, command = None):
  1171.     if os.name == 'nt':
  1172.         format = 'BMP'
  1173.         if not command:
  1174.             command = 'start'
  1175.         
  1176.     elif sys.platform == 'darwin':
  1177.         format = 'JPEG'
  1178.         if not command:
  1179.             command = 'open -a /Applications/Preview.app'
  1180.         
  1181.     else:
  1182.         format = None
  1183.         if not command:
  1184.             command = 'xv'
  1185.             if title:
  1186.                 command = command + ' -name "%s"' % title
  1187.             
  1188.         
  1189.     if image.mode == 'I;16':
  1190.         base = 'L'
  1191.     else:
  1192.         base = getmodebase(image.mode)
  1193.     if base != image.mode and image.mode != '1':
  1194.         file = image.convert(base)._dump(format = format)
  1195.     else:
  1196.         file = image._dump(format = format)
  1197.     if os.name == 'nt':
  1198.         os.system('%s %s' % (command, file))
  1199.     elif sys.platform == 'darwin':
  1200.         os.system('(%s %s; sleep 20; rm -f %s)&' % (command, file, file))
  1201.     else:
  1202.         os.system('(%s %s; rm -f %s)&' % (command, file, file))
  1203.  
  1204.